package com.fdb.efp.nls.service.impl.psd;

import com.fdb.efp.nls.service.facade.psd.QuotaCheckService;
import com.fdb.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.util.TimeUtil;
import com.fdb.basic.framework.core.vo.RetMsgVO;
import com.fdb.basic.framework.redis.lock.RedisLock;
import com.fdb.efp.nls.common.psd.PsdConstantSet;
import com.fdb.efp.nls.service.facade.QuotaLimitPrdService;
import com.fdb.efp.nls.service.vo.QuotaLimitPrdVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
//import redis.clients.jedis.JedisCluster;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;


/**
 * 额度控制服务类
 */
@Service("quotaCheckService")
public class QuotaCheckServiceImpl implements QuotaCheckService, FrameworkService {

    private static Logger logger = LoggerFactory.getLogger(QuotaCheckServiceImpl.class);

    @Autowired
    private QuotaLimitPrdService quotaLimitPrdService;

    @Autowired
    private NlsCreditInfoService nlsCreditInfoService;

//    @Autowired
//    private JedisCluster jedisCluster;
//    //redis单点使用Jedis
    private Jedis jedisCluster;

    @RedisLock(key = "preNlsCreditInfoService_preOccupied")
    @Override
    public RetMsgVO preOccupied(String sxApplySeq, BigDecimal preApproveLimit) throws Exception {
        setHash();
        RetMsgVO check = check(PsdConstantSet.prdId, preApproveLimit);
        if (!check.isRetFlag()) {
            return check;
        }
        //将额度信息保存到redis
        jedisCluster.hset(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY, sxApplySeq, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "_" + preApproveLimit.toString());
        return new RetMsgVO(true, "");
    }

    private void setHash() {
        if (!jedisCluster.exists(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY)) {
            //创建
            HashMap<String, String> map = new HashMap<>();
            map.put("init", TimeUtil.getCurrentDate() + "_" + "0");
            jedisCluster.hmset(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY, map);
        }
    }

    @Override
    public RetMsgVO check(String prdId) throws Exception {
        //查询当前有效的限额配置
        List<QuotaLimitPrdVO> quotaLimitPrdVOS = quotaLimitPrdService.queryPrdActiveQuota(prdId, TimeUtil.getCurrentDate());
        if (quotaLimitPrdVOS == null || quotaLimitPrdVOS.isEmpty()) {
            return new RetMsgVO(true, "");
        }
        for (QuotaLimitPrdVO quotaLimitPrdVO : quotaLimitPrdVOS) {
            BigDecimal arroveLimitTotal = nlsCreditInfoService.queryArroveLimitTotal(quotaLimitPrdVO.getPrdId());
            //获取预防占用额度
            BigDecimal preTotal = getPreOccupieAmt(quotaLimitPrdVO);
            if (arroveLimitTotal.add(preTotal).doubleValue() >= quotaLimitPrdVO.getQuotaLimitAmt().doubleValue()) {
                return new RetMsgVO(false, "已超过最大限制额度");
            }
        }
        return new RetMsgVO(true, "");
    }

    @Override
    public RetMsgVO check(String prdId, BigDecimal approveLimit) throws Exception {
        //查询当前有效的限额配置
        List<QuotaLimitPrdVO> quotaLimitPrdVOS = quotaLimitPrdService.queryPrdActiveQuota(prdId, TimeUtil.getCurrentDate());
        if (quotaLimitPrdVOS == null || quotaLimitPrdVOS.isEmpty()) {
            return new RetMsgVO(true, "");
        }
        for (QuotaLimitPrdVO quotaLimitPrdVO : quotaLimitPrdVOS) {
            //判断限额开始时间和结束时间内的授信审批额度总数是否超过了
            BigDecimal arroveLimitTotal = nlsCreditInfoService.queryArroveLimitTotal(quotaLimitPrdVO.getPrdId());
            //获取预防占用额度
            BigDecimal preTotal = getPreOccupieAmt(quotaLimitPrdVO);
            if (arroveLimitTotal.add(preTotal).add(approveLimit).doubleValue() > quotaLimitPrdVO.getQuotaLimitAmt().doubleValue()) {
                return new RetMsgVO(false, "已超过最大限制额度");
            }
        }
        return new RetMsgVO(true, "");
    }

    @Override
    public void clearPreOccupied(String sxApplySeq) {
        if (StringUtils.isEmpty(sxApplySeq)) {
            return;
        }
        //判断key是否存在
        if (jedisCluster.exists(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY)) {
            if (jedisCluster.hexists(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY,sxApplySeq)) {
                jedisCluster.hdel(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY, sxApplySeq);
            }
        }
    }

    @Override
    public void updatePreOccupied(String sxApplySeq, BigDecimal amt) {
        if (Objects.isNull(amt)) {
            return;
        }
        //判断key是否存在
        if (jedisCluster.exists(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY)) {
            if (jedisCluster.hexists(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY, sxApplySeq)) {
                jedisCluster.hset(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY, sxApplySeq, TimeUtil.getCurrentDate() + "_" + amt.toString());
            }
        }
    }

    private BigDecimal getPreOccupieAmt(QuotaLimitPrdVO quotaLimitPrdVO) {
        BigDecimal preTotal = BigDecimal.ZERO;
        if (jedisCluster.exists(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY)) {
            List<String> hvals = jedisCluster.hvals(PsdConstantSet.PRE_OCCUPIED_REDIS_HASH_KEY);
            for (String hval : hvals) {
                String[] s = hval.split("_");
                LocalDate parse = LocalDate.parse(s[0], DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                preTotal = preTotal.add(new BigDecimal(s[1]));
            }
        }
        return preTotal;
    }
}
